# 使用注册器
class Register(dict):
    def __init__(self, *args, **kwargs):
        super(Register, self).__init__(*args,**kwargs)
        self._dict = {}

    def __call__(self, target):
        return self.register(target)

    def register(self, target):
        def add_item(key, value):
            if not callable(value):
                raise Exception(f"Error:{value} must be callable!")
            if key in self._dict:
                print(f"Warning:{value.__name__} already exists and will be overwritten!")
            self._dict[key]= value
            return self._dict
            
        if callable(target): # 传入的target可调用 ---->没有给注册名 ----> 传入的函数名或类名作为注册名
            return add_item(target.__name__, target)
        else:
            #不可调用 -->传入了注册名 -->作为可调用对象的注册名
            return lambda x : add_item(target, x)

    def __setitem__ (self, key, value): 
        self._dict[key]= value

    def __getitem__ (self, key):
        return self._dict[key]
    
    def __contains__ (self, key):
        return key in self._dict
    
    def __str__(self):
        return str(self._dict)
    
    def keys(self):
        return self._dict.keys()
    
    def values(self):
        return self._dict.values()
    
    def items(self):
        return self._dict.items()

register_func = Register()

@register_func
def add(a, b):
    return a + b

@register_func
def multiply(a, b):
    return a* b

@register_func('matrix multiply')
def multiply(a, b):
    return a * b

@register_func
def minus(a, b):
    return a - b

@register_func
def minus(a, b):
    return a - b

for k, v in register_func.items():
    print(f"key: {k}, value: {v}")